﻿//+-------------------------------------------------------------------------------------------------------------------------------------------------------
//
//Description: ResExtDeploymentParamSettingViewModel
//Author: Aravind Ramarathinam (aravr@microsoft.com)
//
//Copyright © Microsoft Corporation
//Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
//You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
//THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 
//INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 
//See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.
// 
//--------------------------------------------------------------------------------------------------------------------------------------------------------

using System.Collections.Generic;
using System.ComponentModel;
using VmroleAuthor.Models;

namespace VmroleAuthor.ViewModels
{
    public class ResExtDeploymentParamSettingViewModel : ViewModelBase, IDataErrorInfo
    {
        private static readonly List<string> BooleanOptions = new List<string> { "true", "false" };
        private static readonly List<string> NoOptions = new List<string>();

        private readonly ParameterViewModel paramViewModel;  
        private string settingValue;

        private string userName;
        private string secureOrPwd;
        private string confirmSecureOrPwd;

        public ResExtDeploymentParamSettingViewModel(ParameterViewModel parameterViewModel)
        {
            this.paramViewModel = parameterViewModel;
            if (this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.Option
                && this.paramViewModel.ViewDefParamInfo.Options != null
                && this.paramViewModel.ViewDefParamInfo.Options.Count > 0)
            {
                this.settingValue = this.paramViewModel.ViewDefParamInfo.Options[0];
            }
            if (this.paramViewModel.ViewDefParamInfo.DeEscapedDefaultInitialValue != null)
            {
                this.settingValue = this.paramViewModel.ViewDefParamInfo.DeEscapedDefaultInitialValue;
            }
        }

        public static class PropertyNames
        {
            public const string Name = "Name";
            public const string DefaultViewDefType = "DefaultViewDefType";
            public const string IsMultilineString = "IsMultilineString";
            public const string Description = "Description";
            public const string Options = "Options"; 
            public const string SelectedOption = "SelectedOption";
            public const string UserName = "UserName";
            public const string SecureOrPwd = "SecureOrPwd";
            public const string ConfirmSecureOrPwd = "ConfirmSecureOrPwd";        
            public const string SettingValue = "SettingValue";
            public const string ToolTipUserName = "ToolTipUserName";
            public const string ToolTipPassword = "ToolTipPassword";
            public const string ToolTipConfirmPassword = "ToolTipConfirmPassword";
            public const string ToolTipOption = "ToolTipOption";
            public const string ToolTipSecurePassword = "ToolTipSecurePassword";
            public const string ToolTipConfirmSecurePassword = "ToolTipConfirmSecurePassword";
            public const string ToolTipString = "ToolTipString";
        }


        public string Name
        {
            get { return this.paramViewModel.Name; }
        }

        public string DefaultViewDefType
        {
            get { return this.paramViewModel.ViewDefParamInfo.ViewDefParameterType.ToString(); }
        } 
    
        public bool IsMultilineString
        {
            get { return this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.MultiLineString; }
        }

        public string Description
        {
            get { return this.paramViewModel.Description; }
        }

        public string ToolTipUserName
        {
            get { return "Enter the username for the " + this.paramViewModel.Description + " setting"; }
        }

        public string ToolTipPassword
        {
            get { return "Enter the password for the " + this.paramViewModel.Description + " setting"; }
        }

        public string ToolTipConfirmPassword
        {
            get { return "Confirm the password for the " + this.paramViewModel.Description + " setting"; }
        }

        public string ToolTipOption
        {
            get { return "Select the option value for the " + this.paramViewModel.Description + " setting"; }
        }

        public string ToolTipSecurePassword
        {
            get { return "Enter the secure value for the " + this.paramViewModel.Description + " setting"; }
        }

        public string ToolTipConfirmSecurePassword
        {
            get { return "Confirm the secure value for the " + this.paramViewModel.Description + " setting"; }
        }

        public string ToolTipString
        {
            get { return "Enter the value for the " + this.paramViewModel.Description + " setting"; }
        }

        public List<string> Options
        {
            get
            {
                if (this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.Option)
                {
                    return this.paramViewModel.ViewDefParamInfo.Options;
                }
                //Note: If ResExtType is changed, underlying viewdefparamtype is also changed.
                if (this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.Boolean)
                {
                    return BooleanOptions;
                }
                return NoOptions; //No options
            }
        }

        public string SelectedOption
        {
            get
            {
                return this.settingValue;
            }
            set
            {               
                if (
                    this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.Option ||
                    this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.Boolean)
                {
                    if (value == null)
                    {
                        return;
                    } 
                    this.settingValue = value;
                    this.OnPropertyChanged(PropertyNames.SelectedOption);
                    this.OnPropertyChanged(PropertyNames.SettingValue);
                }
               
            }
        }

        public string UserName
        {
            get { return this.userName; }
            set
            {
                this.userName = value;
                this.OnPropertyChanged(PropertyNames.UserName);
            }
        }

        public string SecureOrPwd
        {
            get { return this.secureOrPwd; }
            set 
            { 
                this.secureOrPwd = value;
                this.OnPropertyChanged(PropertyNames.SecureOrPwd );
                this.OnPropertyChanged(PropertyNames.ConfirmSecureOrPwd);  
            }
        }

        public string ConfirmSecureOrPwd
        {
            get { return this.confirmSecureOrPwd; }
            set 
            { 
                this.confirmSecureOrPwd = value;
                this.OnPropertyChanged(PropertyNames.ConfirmSecureOrPwd );
                this.OnPropertyChanged(PropertyNames.SecureOrPwd);             
            }           
        }
       
        public string SettingValue
        {
            get
            {
                if (this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.Credential &&
                    !string.IsNullOrEmpty(this.UserName))
                {
                    this.settingValue = string.Format("{0}:{1}", this.userName, this.secureOrPwd ?? string.Empty);
                }
                else if (this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.SecureString)
                {
                    this.settingValue = this.secureOrPwd ?? string.Empty;
                }
                return this.settingValue;                
            }
            set
            {
                this.settingValue = value;
                this.OnPropertyChanged(PropertyNames.SettingValue);
            }
        }


        public bool IsParameterSettingAvailable
        {
            get
            {             
               if (this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.Credential)
               {
                   bool userNameAvailable = !string.IsNullOrEmpty(this.userName);
                   bool pwdMatches = string.IsNullOrEmpty(this.secureOrPwd) ? string.IsNullOrEmpty(this.confirmSecureOrPwd): this.secureOrPwd.Equals(this.confirmSecureOrPwd);
                   return userNameAvailable && pwdMatches;
               }
               if (this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.SecureString)
               {
                   bool pwdMatches = string.IsNullOrEmpty(this.secureOrPwd) ? string.IsNullOrEmpty(this.confirmSecureOrPwd) : this.secureOrPwd.Equals(this.confirmSecureOrPwd);
                   return pwdMatches;
               }
               return this.SettingValue != null;
            }
        }

        public string this[string propertyName]
        {
            get
            {
                string error = null;
                switch (propertyName)
                {
                    case PropertyNames.ConfirmSecureOrPwd:
                        if (
                            (this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.SecureString) ||
                            (this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.Credential)
                            )
                        {
                            bool pwdMatches = string.IsNullOrEmpty(this.secureOrPwd) ? string.IsNullOrEmpty(this.confirmSecureOrPwd) : this.secureOrPwd.Equals(this.confirmSecureOrPwd);
                            if (!pwdMatches)
                            {
                                error = "Does not match";
                            }
                        }
                        break;
                    case PropertyNames.UserName:
                        if ((this.paramViewModel.ViewDefParamInfo.ViewDefParameterType == ViewDefParameterType.Credential) &&
                            string.IsNullOrEmpty(this.userName))
                        {
                            error = "Cannot be empty";
                        }
                        break;
                    case PropertyNames.Options:
                    case PropertyNames.SelectedOption:
                    case PropertyNames.SettingValue:
                        if (this.SettingValue == null)
                        {
                            error = "Value must be specified";
                        }
                        break;
                }
                return error;
            }
        }

        public string Error { get; set; }
    }
}
